package com.dh.spring.thread;

import com.dh.spring.util.LocalTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.util.concurrent.Callable;

/**
 * 线程池任务拒绝策略
 * */
@FunctionalInterface
public interface CustomAbortPolicy {
    public static final Logger logger = LoggerFactory.getLogger(CustomAbortPolicy.class);

    void reject(Object object, CustomThreadPool customThreadPool) throws Exception;

    //TODO 直接拒绝和丢弃掉任务
    class DiscardPolicy implements CustomAbortPolicy {
        @Override
        public void reject(Object object, CustomThreadPool customThreadPool) {
            logger.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ]" + " 由于配置了DiscardPolicy任务拒绝策略，将直接丢弃掉任务......");
            return;
        }
    }

    //TODO 拒绝并抛弃异常
    class RejectPolicy implements CustomAbortPolicy {
        @Override
        public void reject(Object object, CustomThreadPool customThreadPool) throws Exception {
            logger.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ]" + " 由于配置了RejectPolicy任务拒绝策略，将抛出异常拒绝异常......");
            throw new CustomDenyPolicyException("线程池任务队列已满，将拒绝任务入队操作");
        }
    }

    //TODO 交由任务提交者所在线程执行相应任务
    class MainThreadPolicy implements CustomAbortPolicy {
        @Override
        public void reject(Object object, CustomThreadPool customThreadPool) {
            if(!customThreadPool.isShutdown()) {
                if(null != object && object instanceof Runnable) {
                    ((Runnable) object).run();
                }

                if(null != object && object instanceof Callable) {
                    try {
                        ((Callable) object).call();
                    } catch (Exception e) {
                        logger.info("[ " + LocalTime.formatDate(LocalDateTime.now()) + " ]" + " 由于配置了MainThreadPolicy任务拒绝策略，执行Call方法出现Exception异常......");
                        throw new CustomDenyPolicyException("线程池任务队列已满，将拒绝任务入队操作");
                    }
                }
            }
        }
    }

    //TODO 自定义拒绝策略异常
    class CustomDenyPolicyException extends RuntimeException {
        public CustomDenyPolicyException(String exception) {
            super(exception);
        }
    }
}
